package com.ndood.common.base.util;

import java.math.BigInteger;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.lang.StringUtils;

/**
 * AES加密解密工具类
 */
public class AesEncryptUtil {

	/**
	 * 加密
	 */
	public static String encrypt(String src, String key) throws Exception {
		// 判断密钥是否为空
		if (StringUtils.isBlank(key)) {
			throw new Exception("密钥不能为空");
		}

		// 密钥补位
		int plus = 16 - key.length();
		byte[] data = key.getBytes("utf-8");
		byte[] raw = new byte[16];
		byte[] plusbyte = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
				0x0f };
		for (int i = 0; i < 16; i++) {
			if (data.length > i)
				raw[i] = data[i];
			else
				raw[i] = plusbyte[plus];
		}

		SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
		Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); // 算法/模式/补码方式
		cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
		byte[] encrypted = cipher.doFinal(src.getBytes("utf-8"));

		// return new Base64().encodeToString(encrypted);//base64
		return binary(encrypted, 16); // 十六进制
	}

	/**
	 * 解密
	 */
	public static String decrypt(String src, String key) throws Exception {
		try {
			// 判断Key是否正确
			if (StringUtils.isBlank(key)) {
				throw new Exception("密钥不能为空");
			}

			// 密钥补位
			int plus = 16 - key.length();
			byte[] data = key.getBytes("utf-8");
			byte[] raw = new byte[16];
			byte[] plusbyte = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
					0x0e, 0x0f };
			for (int i = 0; i < 16; i++) {
				if (data.length > i)
					raw[i] = data[i];
				else
					raw[i] = plusbyte[plus];
			}

			SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
			Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
			cipher.init(Cipher.DECRYPT_MODE, skeySpec);

			byte[] encrypted1 = toByteArray(src);// 十六进制

			byte[] original = cipher.doFinal(encrypted1);
			String originalString = new String(original, "utf-8");
			return originalString;
		} catch (Exception ex) {
			throw new Exception("AES解密失败" + ex.getMessage());
		}
	}

	/**
	 * 将byte[]转为各种进制的字符串
	 * 
	 * @param bytes
	 *            byte[]
	 * @param radix
	 *            可以转换进制的范围，从Character.MIN_RADIX到Character.MAX_RADIX，超出范围后变为10进制
	 * @return 转换后的字符串
	 */
	public static String binary(byte[] bytes, int radix) {
		return new BigInteger(1, bytes).toString(radix); // 这里的1代表正数
	}

	/**
	 * 16进制的字符串表示转成字节数组
	 *
	 * @param hexString
	 *            16进制格式的字符串
	 * @return 转换后的字节数组
	 **/
	public static byte[] toByteArray(String hexString) {
		if (hexString.isEmpty())
			throw new IllegalArgumentException("this hexString must not be empty");

		hexString = hexString.toLowerCase();
		final byte[] byteArray = new byte[hexString.length() / 2];
		int k = 0;
		for (int i = 0; i < byteArray.length; i++) {// 因为是16进制，最多只会占用4位，转换成字节需要两个16进制的字符，高位在先
			byte high = (byte) (Character.digit(hexString.charAt(k), 16) & 0xff);
			byte low = (byte) (Character.digit(hexString.charAt(k + 1), 16) & 0xff);
			byteArray[i] = (byte) (high << 4 | low);
			k += 2;
		}
		return byteArray;
	}

	/*public static void main(String[] args) throws Exception {
		// 密钥
		String key = "smph2015120shao123232312312312312312312312312312312313212312312";
		// 需要加密的字符串
		String src = "出版社1231231231231231213123sdadfadfasfdadfasdfsfadsfasdf";

		System.out.println(src);

		// 加密
		String enString = Encrypt(src, key);
		System.out.println("加密后的字串是：" + enString);

		// 解密
		String DeString = Decrypt(enString, key);
		System.out.println("解密后的字串是：" + DeString);
	}*/

}
